package ph.com.gs3.formalistics.custom.implementation;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.formalistics.R;
import ph.com.gs3.formalistics.global.interfaces.CommonCallbackCommand;
import ph.com.gs3.formalistics.global.utilities.DateUtilities;
import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;
import ph.com.gs3.formalistics.model.facades.DocumentsDataReader;
import ph.com.gs3.formalistics.model.facades.FormsDataReader;
import ph.com.gs3.formalistics.model.vo.application.SearchCondition;
import ph.com.gs3.formalistics.model.vo.business.User;
import ph.com.gs3.formalistics.model.vo.business.document.DocumentHeaderData;
import ph.com.gs3.formalistics.model.vo.business.form.Form;
import ph.com.gs3.formalistics.model.vo.business.form.FormFieldData;
import ph.com.gs3.formalistics.model.vo.business.form.FormViewContentData;
import ph.com.gs3.formalistics.view.document.DocumentViewContentsManager;
import ph.com.gs3.formalistics.view.document.abstractfields.AbstractFieldView;
import ph.com.gs3.formalistics.view.document.specialfields.BarcodeScannerField;
import ph.com.gs3.formalistics.view.document.specialfields.BarcodeScannerField.BarcodeScannerListener;
import android.app.Activity;
import android.content.Context;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintJob;
import android.print.PrintManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class SmartmaticDocumentViewContentsManager implements DocumentViewContentsManager {

	public static final String TAG = SmartmaticDocumentViewContentsManager.class.getSimpleName();

	public static final String SERIAL_NUMBER_MAINTENANCE_FORM_ID = "327";
	public static final String HARDWARE_TEST_FORM_ID = "324";

	private Context context;
	private User currentUser;

	private BarcodeScannerListener barcodeScannerListener;
	private SmartmaticDocumentView smartmaticDocumentView;

	private Form serialNumberMaintenanceForm;

	private List<FormViewContentData> formViewContentDataList;

	private DocumentHeaderData documentHeaderData;
	private SmartmaticBackend backend;

	private String[] statusSelection = { "--Select--", "Passed", "Failed" };

	private ArrayAdapter<String> adapter;

	private WebView currentlyPrintingWebView;
	private List<PrintJob> printJobList;

	// ===============================================================
	// {{ All Fields

	private Button SmartHTF_bPrint;

	// ===============================================================
	// {{ Top View Fields

	private EditText SmartHTF_etValidator;

	private EditText SmartHTF_etControlNo;
	private EditText SmartHTF_etDate;
	private EditText SmartHTF_etBoxSerialNo;
	private EditText SmartHTF_etMachineSerialNo;
	private EditText SmartHTF_etAssetTagNo;
	private EditText SmartHTF_etProductName;
	private EditText SmartHTF_etDeviceType;
	private EditText SmartHTF_etDimensionsOrGrossWeight;
	private EditText SmartHTF_etBatchNo;
	private EditText SmartHTF_etStatus;

	private Button SmartHTF_bScanBoxSerialNo;
	private Button SmartHTF_bScanMachineSerialNo;

	// }}

	// ===============================================================
	// {{ Middle View Fields

	private EditText SmartHTF_etPCOSQuantity;
	private EditText SmartHTF_etAdaptorQuantity;
	private EditText SmartHTF_etContainerBoxQuantity;
	private EditText SmartHTF_etPlasticSleeveQuantity;
	private EditText SmartHTF_etSilicaGelQuantity;
	private EditText SmartHTF_etStyroHolderQuantity;

	private EditText SmartHTF_etPCOSRemarks;
	private EditText SmartHTF_etAdaptorRemarks;
	private EditText SmartHTF_etContainerBoxRemarks;
	private EditText SmartHTF_etPlasticSleeveRemarks;
	private EditText SmartHTF_etSilicaGelRemarks;
	private EditText SmartHTF_etStyroHolderRemarks;

	// }}

	// ===============================================================
	// {{ Diagnostic Test Fields

	private int[] diagnosticStatusIdList = { R.id.SmartHTF_swDiagnostic1_1Status,
	        R.id.SmartHTF_swDiagnostic1_2Status, R.id.SmartHTF_swDiagnostic1_3Status,
	        R.id.SmartHTF_swDiagnostic1_4Status, R.id.SmartHTF_swDiagnostic1_5Status,
	        R.id.SmartHTF_swDiagnostic2_1Status, R.id.SmartHTF_swDiagnostic2_2Status,
	        R.id.SmartHTF_swDiagnostic2_3Status, R.id.SmartHTF_swDiagnostic2_4Status,
	        R.id.SmartHTF_swDiagnostic2_5Status, R.id.SmartHTF_swDiagnostic2_6Status,
	        R.id.SmartHTF_swDiagnostic2_7Status, R.id.SmartHTF_swDiagnostic2_8Status,
	        R.id.SmartHTF_swDiagnostic2_9Status, R.id.SmartHTF_swDiagnostic2_10Status,
	        R.id.SmartHTF_swDiagnostic2_11Status, R.id.SmartHTF_swDiagnostic2_12Status,
	        R.id.SmartHTF_swDiagnostic2_13Status, };

	private int[] diagnosticRemarksIdList = { R.id.SmartHTF_etDiagnostic1_1Remarks,
	        R.id.SmartHTF_etDiagnostic1_2Remarks, R.id.SmartHTF_etDiagnostic1_3Remarks,
	        R.id.SmartHTF_etDiagnostic1_4Remarks, R.id.SmartHTF_etDiagnostic1_5Remarks,
	        R.id.SmartHTF_etDiagnostic2_1Remarks, R.id.SmartHTF_etDiagnostic2_2Remarks,
	        R.id.SmartHTF_etDiagnostic2_3Remarks, R.id.SmartHTF_etDiagnostic2_4Remarks,
	        R.id.SmartHTF_etDiagnostic2_5Remarks, R.id.SmartHTF_etDiagnostic2_6Remarks,
	        R.id.SmartHTF_etDiagnostic2_7Remarks, R.id.SmartHTF_etDiagnostic2_8Remarks,
	        R.id.SmartHTF_etDiagnostic2_9Remarks, R.id.SmartHTF_etDiagnostic2_10Remarks,
	        R.id.SmartHTF_etDiagnostic2_11Remarks, R.id.SmartHTF_etDiagnostic2_12Remarks,
	        R.id.SmartHTF_etDiagnostic2_13Remarks };

	private List<Switch> swDiagnosticStatusList;
	private List<EditText> etDiagnosticsRemarksList;

	// }}

	// ===============================================================
	// {{ Cleaning Fields

	private int[] cleaningStatusIdList = { R.id.SmartHTF_swCleaning1Status,
	        R.id.SmartHTF_swCleaning2Status, R.id.SmartHTF_swCleaning3Status,
	        R.id.SmartHTF_swCleaning4Status, R.id.SmartHTF_swCleaning5Status };

	private int[] cleaningRemarksIdList = { R.id.SmartHTF_etCleaning1Remarks,
	        R.id.SmartHTF_etCleaning2Remarks, R.id.SmartHTF_etCleaning3Remarks,
	        R.id.SmartHTF_etCleaning4Remarks, R.id.SmartHTF_etCleaning5Remarks };

	private List<Switch> swCleaningStatusList;

	// }}

	// ===============================================================
	// {{ Footer Fields

	private LinearLayout SmartHTF_llOperatorAndComelecRepContainer2;

	private EditText SmartHTF_etOperator1;
	private EditText SmartHTF_etOperator1TableNo;
	private EditText SmartHTF_etOperator1EMPNo;

	private EditText SmartHTF_etOperator2;
	private EditText SmartHTF_etOperator2TableNo;
	private EditText SmartHTF_etOperator2EMPNo;

	private EditText SmartHTF_etComelectRep1;
	private EditText SmartHTF_etComelectRep1TableNo;

	private EditText SmartHTF_etComelectRep2;
	private EditText SmartHTF_etComelectRep2TableNo;

	// }}

	// }}

	public SmartmaticDocumentViewContentsManager(Context context) {
		this.context = context;

		backend = new SmartmaticBackend();

		adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,
		        statusSelection);

		printJobList = new ArrayList<>();

	}

	// ===============================================================
	// {{ DocumentViewContentsManager Implementation Methods

	@Override
	public View getCreatedDocumentViewContentsContainer() {
		return smartmaticDocumentView;
	}

	@Override
	public void createDocumentViewsFromData(List<FormViewContentData> formViewContentDataList,
	        JSONObject fieldValues, DocumentHeaderData documentHeaderData, User currentUser) {

		this.currentUser = currentUser;
		this.documentHeaderData = documentHeaderData;

		smartmaticDocumentView = new SmartmaticDocumentView(context);

		this.formViewContentDataList = formViewContentDataList;

		SmartHTF_bPrint = (Button) smartmaticDocumentView.findViewById(R.id.SmartHTF_bPrint);

		if (documentHeaderData.getStatus() != null) {

			final DocumentHeaderData dataReference = documentHeaderData;

			SmartHTF_bPrint.setVisibility(View.VISIBLE);
			SmartHTF_bPrint.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					backend.getPrintableHTMLOfDocument(dataReference.getWebId(),
					        new CommonCallbackCommand() {

						        @Override
						        public void execute(Object... params) {

							        SmartHTF_bPrint.setEnabled(true);

							        if (params != null && params.length > 0 && params[0] != null) {
								        String htmlToPrint = params[0].toString();

								        String jobName = "Hardware Test Form Document "
								                + dataReference.getTrackingNumber();
								        SmartmaticPrintingUtility.print(context, htmlToPrint,
								                jobName);
							        } else {
								        FLLogger.e(TAG, "Unable to print, no view to print");
							        }

						        }
					        });

					SmartHTF_bPrint.setEnabled(false);
				}
			});
		}

		initializeTopViewFields();
		initializeMiddleViewFields();
		initializeDiagnosticTestViewFields();
		initializeFooterViewFields();
		initializeButtonFields();

		for (FormViewContentData data : formViewContentDataList) {
			try {
				setFieldValue(data.getId(), fieldValues.getString(data.getId()));
			} catch (JSONException e) {
				FLLogger.w(TAG, "Unable to set value of " + data.getId() + "; " + e.getMessage());
			}
		}

		// Disable all fields first:
		setControlsEnabled(false, smartmaticDocumentView);

		for (String fieldEnabled : documentHeaderData.getFieldsEnabled()) {
			View view = smartmaticDocumentView.findViewWithTag(fieldEnabled);
			if (view != null) {
				view.setEnabled(true);
			}
		}

		for (String fieldHidden : documentHeaderData.getFieldsHidden()) {
			View view = smartmaticDocumentView.findViewWithTag(fieldHidden);
			if (view != null) {
				view.setVisibility(View.INVISIBLE);
			}
		}
	}

	@Override
	public void setSpecialFieldsListener(Activity activity) {
		this.barcodeScannerListener = (BarcodeScannerListener) activity;
	}

	@Override
	public View findFieldView(String fieldId) {
		return smartmaticDocumentView.findViewWithTag(fieldId);
	}

	@Override
	public void setFieldValue(String fieldId, String value) {

		View view = smartmaticDocumentView.findViewWithTag(fieldId);

		if (view != null) {

			if (view instanceof EditText) {
				((EditText) view).setText(value);

				if ("SerialMachine".equals(fieldId)) {
					search();
				}

			} else if (view instanceof Spinner) {

				for (int i = 0; i < statusSelection.length; i++) {
					if (statusSelection[i].equals(value)) {
						((Spinner) view).setSelection(i);
					}
				}
			} else if (view instanceof Switch) {
				((Switch) view).setChecked("Passed".equalsIgnoreCase(value.trim()));
			} else {
				FLLogger.w(TAG, "Unable to set value of field " + fieldId
				        + ", field type not supported");
			}

		} else {
			FLLogger.w(TAG, "Unable to set value of field " + fieldId + ", field not found");
		}
	}

	public String getFieldValue(String fieldId) {

		View view = smartmaticDocumentView.findViewWithTag(fieldId);

		if ("Date1".equalsIgnoreCase(fieldId)) {
			String rawDate = SmartHTF_etDate.getText().toString();
			try {
				Date date = DateUtilities.DEFAULT_DISPLAY_DATE_ONLY_FORMAT.parse(rawDate);
				return DateUtilities.SERVER_DATE_TIME_FORMAT.format(date);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		if (view != null) {
			if (view instanceof EditText) {
				return ((EditText) view).getText().toString();
			} else if (view instanceof Spinner) {
				return ((Spinner) view).getSelectedItem().toString();
			} else if (view instanceof Switch) {
				return ((Switch) view).isChecked() ? "Passed" : "Failed";
			}
		}

		return null;

	}

	@Override
	public JSONObject getFieldValues() {

		JSONObject fieldValues = new JSONObject();

		for (FormViewContentData data : formViewContentDataList) {
			String value = getFieldValue(data.getId());

			if (value != null) {
				try {
					fieldValues.put(data.getId(), value);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		fieldValues = modifyFieldValuesBeforeSending(fieldValues);

		FLLogger.d(TAG, fieldValues.toString());

		return fieldValues;
	}

	// }}

	// ===============================================================
	// {{ View Initializers

	private void initializeTopViewFields() {

		SmartHTF_etValidator = (EditText) smartmaticDocumentView
		        .findViewById(R.id.SmartHTF_etValidator);

		// @formatter:off
		SmartHTF_etControlNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etControlNo);
		SmartHTF_etDate = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etDate);
		SmartHTF_etBoxSerialNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etBoxSerialNo);
		SmartHTF_etMachineSerialNo = (EditText) smartmaticDocumentView .findViewById(R.id.SmartHTF_etMachineSerialNo);
		SmartHTF_etAssetTagNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etAssetTagNo);
		SmartHTF_etProductName = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etProductName);
		SmartHTF_etDeviceType = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etDeviceType);
		SmartHTF_etDimensionsOrGrossWeight = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etDimensionsOrGrossWeight);
		SmartHTF_etBatchNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etBatchNo);
		SmartHTF_etStatus = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etStatus);
		
		SmartHTF_bScanBoxSerialNo = (Button) smartmaticDocumentView.findViewById(R.id.SmartHTF_bScanBoxSerialNo);
		SmartHTF_bScanMachineSerialNo = (Button) smartmaticDocumentView.findViewById(R.id.SmartHTF_bScanMachineSerialNo);
		// @formatter:on

		// Map the mobile objects to the formalistics fields
		SmartHTF_etValidator.setTag("Validator");

		SmartHTF_etControlNo.setTag("ControlNo");
		SmartHTF_etDate.setTag("Date1");
		SmartHTF_etBoxSerialNo.setTag("SerialBox");
		SmartHTF_etMachineSerialNo.setTag("SerialMachine");
		SmartHTF_etAssetTagNo.setTag("AssetTagNo");
		SmartHTF_etProductName.setTag("ProductName");
		SmartHTF_etDeviceType.setTag("DeviceType");
		SmartHTF_etDimensionsOrGrossWeight.setTag("Dimensions");
		SmartHTF_etBatchNo.setTag("BatchNo");
		SmartHTF_etStatus.setTag("MachineStatus");

	}

	private void initializeMiddleViewFields() {

		// @formatter:off
		SmartHTF_etPCOSQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etPCOSQuantity);
		SmartHTF_etAdaptorQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etAdaptorQuantity);
		SmartHTF_etContainerBoxQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etContainerBoxQuantity);
		SmartHTF_etPlasticSleeveQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etPlasticSleeveQuantity);
		SmartHTF_etSilicaGelQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etSilicaGelQuantity);
		SmartHTF_etStyroHolderQuantity = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etStyroHolderQuantity);
		
		SmartHTF_etPCOSRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etPCOSRemarks);
		SmartHTF_etAdaptorRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etAdaptorRemarks);
		SmartHTF_etContainerBoxRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etContainerBoxRemarks);
		SmartHTF_etPlasticSleeveRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etPlasticSleeveRemarks);
		SmartHTF_etSilicaGelRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etSilicaGelRemarks);
		SmartHTF_etStyroHolderRemarks = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etStyroHolderRemarks);
		// @formatter:on

		// Map the mobile objects to the formalistics fields
		SmartHTF_etPCOSQuantity.setTag("Quantity1");
		SmartHTF_etAdaptorQuantity.setTag("Quantity2");
		SmartHTF_etContainerBoxQuantity.setTag("quantity3");
		SmartHTF_etPlasticSleeveQuantity.setTag("quantity4");
		SmartHTF_etSilicaGelQuantity.setTag("quantity5");
		SmartHTF_etStyroHolderQuantity.setTag("quantity6");

		SmartHTF_etPCOSRemarks.setTag("Remarks1");
		SmartHTF_etAdaptorRemarks.setTag("Remarks2");
		SmartHTF_etContainerBoxRemarks.setTag("Remarks3");
		SmartHTF_etPlasticSleeveRemarks.setTag("Remarks4");
		SmartHTF_etSilicaGelRemarks.setTag("Remarks5");
		SmartHTF_etStyroHolderRemarks.setTag("Remarks6");

	}

	private void initializeDiagnosticTestViewFields() {

		swDiagnosticStatusList = new ArrayList<>();
		etDiagnosticsRemarksList = new ArrayList<>();

		swCleaningStatusList = new ArrayList<>();

		for (int i = 0; i < diagnosticStatusIdList.length; i++) {
			Switch swDiagnosticStatus = (Switch) smartmaticDocumentView
			        .findViewById(diagnosticStatusIdList[i]);

			swDiagnosticStatus.setTag("Status" + (i + 1));
			// swDiagnosticStatus.setAdapter(adapter);

			swDiagnosticStatusList.add(swDiagnosticStatus);

		}

		for (int i = 0; i < diagnosticRemarksIdList.length; i++) {
			EditText etDiagnosticsRemarks = (EditText) smartmaticDocumentView
			        .findViewById(diagnosticRemarksIdList[i]);

			etDiagnosticsRemarks.setTag("Remarks" + (i + 7));

			etDiagnosticsRemarksList.add(etDiagnosticsRemarks);

		}

		for (int i = 0; i < cleaningStatusIdList.length; i++) {
			Switch swCleaningStatus = (Switch) smartmaticDocumentView
			        .findViewById(cleaningStatusIdList[i]);
			swCleaningStatus.setTag("Status" + (i + 19));
			swCleaningStatusList.add(swCleaningStatus);
		}

		for (int i = 0; i < cleaningRemarksIdList.length; i++) {
			EditText etDiagnosticsRemarks = (EditText) smartmaticDocumentView
			        .findViewById(cleaningRemarksIdList[i]);
			etDiagnosticsRemarks.setTag("Remarks" + (i + 25));
		}

	}

	private void initializeFooterViewFields() {

		SmartHTF_llOperatorAndComelecRepContainer2 = (LinearLayout) smartmaticDocumentView
		        .findViewById(R.id.SmartHTF_llOperatorAndComelecRepContainer2);

		// @formatter:off				
		SmartHTF_etOperator1 = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator1);
		SmartHTF_etOperator1TableNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator1TableNo);
		SmartHTF_etOperator1EMPNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator1EMPNo);
		
		SmartHTF_etOperator2 = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator2);
		SmartHTF_etOperator2TableNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator2TableNo);
		SmartHTF_etOperator2EMPNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etOperator2EMPNo);
		
		SmartHTF_etComelectRep1 = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etComelectRep1);
		SmartHTF_etComelectRep1TableNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etComelectRep1TableNo);
		
		SmartHTF_etComelectRep2 = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etComelectRep2);
		SmartHTF_etComelectRep2TableNo = (EditText) smartmaticDocumentView.findViewById(R.id.SmartHTF_etComelectRep2TableNo);
		// @formatter:on

		SmartHTF_etOperator1.setTag("SMTOperator1");
		SmartHTF_etOperator1TableNo.setTag("Table1");
		SmartHTF_etOperator1EMPNo.setTag("Emp1");

		SmartHTF_etOperator2.setTag("SMTOperator2");
		SmartHTF_etOperator2TableNo.setTag("Table2");
		SmartHTF_etOperator2EMPNo.setTag("Emp2");

		SmartHTF_etComelectRep1.setTag("Comelec1");
		SmartHTF_etComelectRep1TableNo.setTag("Table3");

		SmartHTF_etComelectRep2.setTag("Comelec2");
		SmartHTF_etComelectRep2TableNo.setTag("Table4");

	}

	private void initializeButtonFields() {

		SmartHTF_bScanBoxSerialNo = (Button) smartmaticDocumentView
		        .findViewById(R.id.SmartHTF_bScanBoxSerialNo);
		SmartHTF_bScanMachineSerialNo = (Button) smartmaticDocumentView
		        .findViewById(R.id.SmartHTF_bScanMachineSerialNo);

		SmartHTF_bScanBoxSerialNo.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				FormFieldData data = new FormFieldData();
				data.setId(SmartHTF_etBoxSerialNo.getTag().toString());

				BarcodeScannerField barcodeScannerField = new BarcodeScannerField(context, data);
				barcodeScannerListener.onScanCodeCommand(barcodeScannerField);
			}
		});

		SmartHTF_bScanMachineSerialNo.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				FormFieldData data = new FormFieldData();
				data.setId(SmartHTF_etMachineSerialNo.getTag().toString());

				BarcodeScannerField barcodeScannerField = new BarcodeScannerField(context, data);
				barcodeScannerListener.onScanCodeCommand(barcodeScannerField);
			}
		});

	}

	// }}

	// ===============================================================
	// {{ Events

	@Override
	public void onLoad() {
		String today = DateUtilities.DEFAULT_DISPLAY_DATE_ONLY_FORMAT.format(new Date());

		if (documentHeaderData.getStatus() == null) {
			SmartHTF_llOperatorAndComelecRepContainer2.setVisibility(View.GONE);
		}

		// @GivenIf((@Status == ''),@Today, @Date1)
		if (documentHeaderData.getStatus() == null) {
			SmartHTF_etDate.setText(today);
		}

		if (documentHeaderData.getStatus() == null) {
			SmartHTF_etStatus.setText("New");
		} else {
			boolean allPassed = true;
			for (Switch swDiagnosticStatus : swDiagnosticStatusList) {
				if (!swDiagnosticStatus.isPressed()) {
					allPassed = false;
					break;
				}
			}

			for (Switch swCleaningStatus : swCleaningStatusList) {
				if (!swCleaningStatus.isPressed()) {
					allPassed = false;
					break;
				}
			}

			if (allPassed) {
				SmartHTF_etStatus.setText("Diagnosed Good");
			} else {
				SmartHTF_etStatus.setText("Diagnosed Quarantine");
			}
		}

		if (documentHeaderData.getStatus() == null) {
			SmartHTF_etOperator1.setText(currentUser.getDisplayName());
		} else {
			SmartHTF_etOperator2.setText(currentUser.getDisplayName());
		}

		/*
		 * 
		 * @GivenIf((@Status == 'For Review'),
		 * 
		 * @StrConcat(@ThisDate(@Today).formatDate('Y'), @ThisDate(@Today).formatDate('d')
		 * ,@ThisDate(@Today).formatDate('m') , '-' , @StrRight(@TrackingNumber,
		 * 4)),@ControlNo)
		 */
		if ("For Review".equals(documentHeaderData.getStatus())) {

			SimpleDateFormat controlNoDateFormat = new SimpleDateFormat("yyyyddmm", Locale.ENGLISH);
			String controlNoDate = controlNoDateFormat.format(new Date());

			int trackingNumberLength = documentHeaderData.getTrackingNumber().length();
			String trimmedTrackNo = documentHeaderData.getTrackingNumber().substring(
			        trackingNumberLength - 4, trackingNumberLength);

			SmartHTF_etControlNo.setText(controlNoDate + "-" + trimmedTrackNo);
		}

		SmartHTF_etMachineSerialNo.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {

				if (!hasFocus) {
					search();
				}
			}
		});

		// Manual coded hiding
		if (documentHeaderData.getStatus() == null) {
			LinearLayout SmartHTF_llOperatorAndComelecRepContainer2 = (LinearLayout) smartmaticDocumentView
			        .findViewById(R.id.SmartHTF_llOperatorAndComelecRepContainer2);

			SmartHTF_llOperatorAndComelecRepContainer2.setVisibility(View.GONE);

		}

	}

	private JSONObject modifyFieldValuesBeforeSending(JSONObject fieldValues) {

		// Add hidden values
		/*
		 * Operator1 = @GivenIf((@Status == '' || @Status == 'For Testing by
		 * Operator'),@CurrentUser,@SMTOperator1)
		 * 
		 * Operator2 = @GivenIf((@Status != ''),@CurrentUser,@SMTOperator2)
		 */

		String status = documentHeaderData.getStatus();

		try {
			if (status == null || "For Testing by Operator".equalsIgnoreCase(status)) {
				fieldValues.put("Operator1", currentUser.getDisplayName());
			} else {
				fieldValues.put("Operator1", getFieldValue("SMTOperator1"));
			}

			if (status == null) {
				fieldValues.put("Operator2", getFieldValue("SMTOperator2"));
			}

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return fieldValues;

	}

	// }}

	private void setControlsEnabled(boolean enable, ViewGroup vg) {
		for (int i = 0; i < vg.getChildCount(); i++) {
			View child = vg.getChildAt(i);
			if (child instanceof ViewGroup) {
				setControlsEnabled(enable, (ViewGroup) child);
			} else if (child instanceof EditText || child instanceof Spinner) {
				child.setEnabled(enable);
			}
		}
	}

	private abstract static class DelayedTextWatcher implements TextWatcher {

		private Timer timer = new Timer();

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

		@Override
		public void onTextChanged(CharSequence s, int start, int before, int count) {
			FLLogger.d(TAG, "Change: " + s.toString());
		}

		@Override
		public void afterTextChanged(final Editable s) {
			timer.cancel();
			timer = new Timer();
			timer.schedule(new TimerTask() {
				@Override
				public void run() {
					onDelayedChange(s.toString());
				}
			}, 2000);
		}

		public abstract void onDelayedChange(String newValue);

	}

	@Override
	public void notifyFieldsRequired(List<String> fieldsThatFailedValidation) {

		for (String fieldId : fieldsThatFailedValidation) {
			View field = smartmaticDocumentView.findViewWithTag(fieldId);

			if (field instanceof TextView) {
				((EditText) field).setError(AbstractFieldView.PROMPT_FIELD_REQUIRED);
			} else {
				FLLogger.e(TAG, "Unsupported field for error message: " + fieldId);
			}

		}

	}

	private void search() {
		String newValue = SmartHTF_etMachineSerialNo.getText().toString();
		String currentSerialBoxNumber = SmartHTF_etBoxSerialNo.getText().toString();

		FLLogger.d(TAG, "Searching for " + newValue);

		// Lazy-load serialNumberMaintenanceForm
		if (serialNumberMaintenanceForm == null) {
			FormsDataReader dataReader = new FormsDataReader(context, currentUser);
			serialNumberMaintenanceForm = dataReader.getForm(SERIAL_NUMBER_MAINTENANCE_FORM_ID,
			        currentUser.getCompany().getId());
		}

		List<String> searchResultFieldNames = new ArrayList<>();
		searchResultFieldNames.add("ProductName");
		searchResultFieldNames.add("DeviceType");
		searchResultFieldNames.add("Dimensions");
		searchResultFieldNames.add("SerialBox");

		List<SearchCondition> searchConditions = new ArrayList<>();
		searchConditions.add(new SearchCondition("SerialNumber", "=", newValue));
		// searchConditions.add(new SearchCondition("SerialBox", "=",
		// currentSerialBoxNumber));

		DocumentsDataReader documentsDataReader = new DocumentsDataReader(context);
		final List<JSONObject> searchResults = documentsDataReader.search(
		        serialNumberMaintenanceForm, searchResultFieldNames, currentUser.getId(),
		        searchConditions);

		FLLogger.d(TAG, "Search result size: " + searchResults.size());

		// ((Activity) context).runOnUiThread(new Runnable() {
		// @Override
		// public void run() {
		if (searchResults.size() > 0) {
			JSONObject searchResult = searchResults.get(0);

			try {
				SmartHTF_etProductName.setText(searchResult.getString("ProductName"));
				SmartHTF_etDeviceType.setText(searchResult.getString("DeviceType"));
				SmartHTF_etDimensionsOrGrossWeight.setText(searchResult.getString("Dimensions"));

				if (!currentSerialBoxNumber.equals(searchResult.getString("SerialBox"))) {
					SmartHTF_etValidator.setText("0");
					Toast.makeText(context, "Box serial number did not match", Toast.LENGTH_LONG)
					        .show();
				} else {
					SmartHTF_etValidator.setText("1");
				}

			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			SmartHTF_etProductName.setText("");
			SmartHTF_etDeviceType.setText("");
			SmartHTF_etDimensionsOrGrossWeight.setText("");
		}
	}

}
